package com.dlc.shop.multishop.controller;

import cn.hutool.core.util.StrUtil;
import com.dlc.shop.allinpay.service.AllinpayCompanyService;
import com.dlc.shop.bean.dto.allinpay.*;
import com.dlc.shop.common.allinpay.constant.AllinpayConstant;
import com.dlc.shop.common.allinpay.constant.AllinpayNoticeUrl;
import com.dlc.shop.common.allinpay.member.constant.VerificationCodeType;
import com.dlc.shop.common.allinpay.member.resp.BindCard;
import com.dlc.shop.common.allinpay.member.resp.CompanyInfo;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.config.ShopConfig;
import com.dlc.shop.security.multishop.util.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lanhai
 */
@Tag(name = "通联支付-企业会员接口")
@RestController("mulitshop-allinpay-company")
@AllArgsConstructor
@RequestMapping("/shop/allinpay/company")
public class AllinpayCompanyController {

    private final AllinpayCompanyService allinpayCompanyService;
    private final ShopConfig shopConfig;

    @GetMapping("/createCompanyMember")
    public ServerResponseEntity<Void> createCompanyMember(@RequestParam("bizUserId") String bizUserId) {
        allinpayCompanyService.createCompanyMember(bizUserId);
        return ServerResponseEntity.success();
    }

    @GetMapping("/getCompanyInfo")
    @Operation(summary = "获取企业信息", description = "获取企业信息")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:info')")
    public ServerResponseEntity<CompanyInfo> getCompanyInfo() {
        String bizUserId = getBizUserId();
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
        return ServerResponseEntity.success(companyInfo);
    }

    @GetMapping("/getCompanyInfoById")
    @Operation(summary = "获取企业信息--测试", description = "获取企业信息")
    public ServerResponseEntity<CompanyInfo> getCompanyInfo(@RequestParam("bizUserId") String bizUserId) {
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
        return ServerResponseEntity.success(companyInfo);
    }

    @PostMapping("/sendVerificationCode")
    @Operation(summary = "发送短信验证码", description = "发送短信验证码")
    public ServerResponseEntity<Void> sendVerificationCode(@RequestBody VerificationCodeDTO verificationCodeDTO) {
        String bizUserId = getBizUserId();
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
        if (Objects.equals(verificationCodeDTO.getVerificationCodeType(), VerificationCodeType.BIND_PHONE.value())) {
            // 绑定手机号的前提是还没有绑定过
            if (Objects.nonNull(companyInfo.getPhone())) {
                throw new YamiShopBindException("当前商家账户已经绑定过手机号码，请刷新页面");
            }
        } else if (Objects.equals(verificationCodeDTO.getVerificationCodeType(), VerificationCodeType.UNBIND_PHONE.value())) {
            // 解绑手机号的前提是有绑定过手机号
            if (Objects.isNull(companyInfo.getPhone())) {
                throw new YamiShopBindException("当前商家账户还没绑定手机号码，请刷新页面");
            }
        }
        allinpayCompanyService.sendVerificationCode(bizUserId, verificationCodeDTO);
        return ServerResponseEntity.success();
    }

    @PostMapping("/bindPhone")
    @Operation(summary = "绑定手机", description = "绑定手机")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:bind')")
    public ServerResponseEntity<Void> bindPhone(@RequestBody VerificationCodeDTO verificationCodeDTO) {
        String bizUserId = getBizUserId();
        if (StrUtil.isBlank(verificationCodeDTO.getVerificationCode())) {
            throw new YamiShopBindException("商家绑定手机验证码不能为空");
        }
        // 绑定手机号的前提是还没有绑定过
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
        if (Objects.nonNull(companyInfo.getPhone())) {
            throw new YamiShopBindException("当前账户已经绑定过手机号码，请刷新页面");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        allinpayCompanyService.bindPhone(shopId, verificationCodeDTO);
        allinpayCompanyService.deleteCache(shopId);
        return ServerResponseEntity.success();
    }

    @PutMapping("/unbindPhone")
    @Operation(summary = "解绑手机", description = "解绑手机")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:unbind')")
    public ServerResponseEntity<Void> unbindPhone(@RequestBody VerificationCodeDTO verificationCodeDTO) {
        String bizUserId = getBizUserId();
        // 解绑手机后，用户无法创建订单
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
        // 解绑手机号的前提是有绑定过手机号
        if (Objects.isNull(companyInfo.getPhone())) {
            throw new YamiShopBindException("当前商家账户还没绑定手机号码，请刷新页面");
        }
        if (!Objects.equals(companyInfo.getPhone(), verificationCodeDTO.getPhone())) {
            throw new YamiShopBindException("解绑手机与当前绑定手机不一致");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        allinpayCompanyService.unbindPhone(shopId, verificationCodeDTO);
        allinpayCompanyService.deleteCache(shopId);
        return ServerResponseEntity.success();
    }

    @PostMapping("/applyBindBankCard")
    @Operation(summary = "请求绑定银行卡", description = "请求绑定银行卡-法人")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:bind')")
    public ServerResponseEntity<Void> applyBindBankCard(@RequestBody ApplyBankCardDTO applyBankCardDTO) {
        String bizUserId = getBizUserId();
        Long shopId = SecurityUtils.getShopUser().getShopId();
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
        allinpayCompanyService.applyBindBankCard(shopId, applyBankCardDTO, companyInfo.getLegalName());
        allinpayCompanyService.deleteCache(shopId);
        return ServerResponseEntity.success();
    }

    @PutMapping("/unbindBankCard")
    @Operation(summary = "解绑银行卡", description = "解绑银行卡-法人")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:unbind')")
    public ServerResponseEntity<Void> unbindBankCard(@RequestBody UnbindBankCardDTO unbindBankCardDTO) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        allinpayCompanyService.unbindBankCard(shopId, unbindBankCardDTO);
        allinpayCompanyService.deleteCache(shopId);
        return ServerResponseEntity.success();
    }

    @GetMapping("/queryBankCard")
    @Operation(summary = "查询银行卡", description = "查询银行卡")
    @Parameter(name = "cardNo", description = "银行卡号(不传则查询全部银行卡)")
    public ServerResponseEntity<List<BindCard>> queryBankCard(@RequestParam(value = "cardNo", required = false) String cardNo) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        List<BindCard> bindCards = allinpayCompanyService.queryBankCard(shopId, cardNo)
                .stream().filter(card -> Objects.equals(card.getBindState(), 1)).collect(Collectors.toList());
        return ServerResponseEntity.success(bindCards);
    }

    @PostMapping("/bindCompanyAccount")
    @Operation(summary = "企业会员绑定对公户", description = "企业会员绑定对公户")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:bind')")
    public ServerResponseEntity<Void> bindCompanyAccount(@RequestBody BindCompanyAccountDTO bindCompanyAccountDTO) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        String bizUserId = getBizUserId();
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
        allinpayCompanyService.bindCompanyAccount(shopId, bindCompanyAccountDTO, companyInfo.getCompanyName());
        allinpayCompanyService.deleteCache(shopId);
        return ServerResponseEntity.success();
    }

    @PostMapping("/signAcctProtocol")
    @Operation(summary = "账户提现协议签约", description = "账户提现协议签约")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:sign')")
    public ServerResponseEntity<String> signAcctProtocol(@RequestBody SignAcctProtocolDTO signAcctProtocolDTO) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        String domainUrl = shopConfig.getDomain().getApiDomainName();
        String backUrl = domainUrl + AllinpayNoticeUrl.SIGN_ACCT_PROTOCOL;
        String url = allinpayCompanyService.signAcctProtocol(shopId, backUrl, signAcctProtocolDTO);
        allinpayCompanyService.deleteCache(shopId);
        return ServerResponseEntity.success(url);
    }

    @GetMapping("/signContractQuery")
    @Operation(summary = "账户协议签约查询", description = "账户协议签约查询")
    @PreAuthorize("@pms.hasPermission('shop:allinpayCompany:sign')")
    public ServerResponseEntity<String> signContractQuery(SignAcctProtocolDTO signAcctProtocolDTO) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        String url = allinpayCompanyService.signContractQuery(shopId, signAcctProtocolDTO);
        return ServerResponseEntity.success(url);
    }

    private static String getBizUserId() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        return AllinpayConstant.SHOP + shopId;
    }
}
